"""
服务模块：用户信息
"""

from werkzeug.security import (generate_password_hash, check_password_hash)

from app.common import SQL_DATETIME_FORMAT
from app.common.exception import (InvalidParamException, InvalidUserException)
from app.common.constants import UserInfoConstants
from app.dao.userinfo import UserInfoDao, UserInfo
from app.dto.userinfo import UserInfoDto


class UserInfoService(object):
    """
    用户信息service类
    """

    @classmethod
    def save(cls, item):
        if not isinstance(item, UserInfoDto):
            raise InvalidParamException("参数错误")
        return UserInfoDao.save(item)

    @classmethod
    def save_all(cls, item_list):
        if not (len(item_list) > 0
                and isinstance(item_list, (list, tuple, set))
                and isinstance(item_list[0], UserInfoDto)):
            raise InvalidParamException("参数错误")
        return UserInfoDao.save_all(item_list)

    @classmethod
    def remove_by_id(cls, id_):
        item = UserInfoDao.find_by_id(id_=id_)
        if not item:
            raise InvalidParamException("id为{id_}的股票信息不存在".format(id_=id_))
        return UserInfoDao.remove_by_id(_id)

    @classmethod
    def update_pwd(cls, _id, old_pwd, new_pwd):
        if old_pwd == new_pwd:
            raise InvalidParamException("原密码和新密码不能相同")

        item = UserInfoDao.find_by_id(_id)
        if not item:
            raise InvalidUserException("用户不存在")

        pwd = item.password
        if not check_password_hash(pwd, old_pwd):
            raise InvalidUserException("用户原密码错误")

        item.password = generate_password_hash(new_pwd)
        UserInfoDao.update(item)

    @classmethod
    def update(cls, item):
        if not isinstance(item, UserInfoDto):
            raise InvalidParamException("参数错误")

        return UserInfoDao.update(item)

    @classmethod
    def find_by_name(cls, name):
        item = UserInfoDao.find_by_name(name)
        return cls.__convert_to_view(item)

    @classmethod
    def find_by_id(cls, _id):
        item = UserInfoDao.find_by_id(_id)
        return cls.__convert_to_view(item)

    @classmethod
    def find_all(cls):
        result = list()
        item_list = UserInfoDao.find_all()
        if item_list:
            for item in item_list:
                result.append(cls.__convert_to_view(item))

        return result

    @classmethod
    def page_by_param(cls, page=1, page_size=10, **kwargs):
        page_data = UserInfoDao.page_by_param(page, page_size, **kwargs)
        items = page_data['items']

        new_items = []
        for item in items:
            modify_time = item.modify_time
            modify_time_str = modify_time.strftime(SQL_DATETIME_FORMAT) if modify_time else ""

            mobile = item.mobile
            mobile = mobile if mobile else ""

            result = dict(id=int(item.id),
                          name=item.name,
                          real_name=item.real_name,
                          mobile=mobile,
                          status=int(item.status),
                          status_str=UserInfoConstants.Status.get_value_name(item.status),
                          add_time_str=item.add_time.strftime(SQL_DATETIME_FORMAT),
                          modify_time_str=modify_time_str,
                          )
            new_items.append(result)
        page_data['items'] = new_items

        return page_data

    @classmethod
    def __convert_to_view(cls, item):
        """
        转化成视图对象
        :param item:
        :return:
        """

        result = None
        if isinstance(item, UserInfo):
            mobile = item.mobile
            mobile = mobile if mobile else ""

            avatar = item.avatar
            avatar = avatar if avatar else ""

            result = dict(id=int(item.id),
                          name=item.name,
                          password=item.password,
                          real_name=item.real_name,
                          mobile=mobile,
                          avatar=avatar,
                          status=int(item.status),
                          status_str=UserInfoConstants.Status.get_value_name(item.status),
                          )
        return result
